package com.bw.common.websocket

import android.os.Handler
import android.text.TextUtils
import com.bw.common.BuildConfig
import com.bw.common.utils.LogUtils
import org.java_websocket.handshake.ServerHandshake
import java.net.URI


/**
 * @author:created by hahajing
 * 时间：2024/5/9 0009
 * 企鹅号:444511958
 * 描述:
 */

class WebSocketUtils private constructor(_websocket_url: String?, _listener: ReceiveMsgListener?) {
    var client: ZWebSocketClient? = null
    private var websocket_url: String = BuildConfig.WS_HOST
    private var listener: ReceiveMsgListener?

    /**
     * 设置接收到消息监听
     * @param listener
     */
    fun setListener(listener: ReceiveMsgListener?) {
        this.listener = listener
    }

    /**
     * 初始化WebSocket
     */
    private fun initWS() {
        mHandler?.postDelayed(heartBeatRunnable, HEART_BEAT_RATE) //开启心跳检测
        if (client == null) {
            initWebSocket()
        } else if (!client!!.isOpen) {
            reconnectWs() //进入页面发现断开开启重连
        }
        //AlarmManager
    }

    /**
     * 关闭连接是否资源
     */
    fun destroy() {
        closeConnect()
    }

    /**
     * 初始化websocket
     */
    private fun initWebSocket() {
        LogUtils.e("123", "websocket的地址是：ws://$websocket_url")
        val uri = URI.create("ws://$websocket_url")
        //TODO 创建websocket
        client = object : ZWebSocketClient(uri) {
            override fun onMessage(message: String?) {
                super.onMessage(message)
                if (message != "Heartbeat") {
                    LogUtils.i("123", "websocket收到消息：$message")
                    //                    sendNotification(message);
                    if (listener != null) {
                        listener!!.onReceive(message)
                    }
                }
            }

            override fun onOpen(handshakedata: ServerHandshake?) {
                super.onOpen(handshakedata)
                LogUtils.i("123", "websocket连接成功")
                if (listener != null) {
                    listener!!.onOpen(handshakedata)
                }
            }

            override fun onError(ex: Exception) {
                super.onError(ex)
                LogUtils.i("123", "websocket连接错误：$ex")
                if (listener != null) {
                    listener!!.onError(ex)
                }
            }

            override fun onClose(code: Int, reason: String?, remote: Boolean) {
                super.onClose(code, reason, remote)
                if (code != 1000) {
                    reconnectWs() //意外断开马上重连
                }
                if (listener != null) {
                    listener!!.onClose(code, reason, remote)
                }
                LogUtils.i("123", "websocket断开连接：·code:$code·reason:$reason·remote:$remote")
            }
        }
        //TODO 设置超时时间
        client?.setConnectionLostTimeout(110 * 1000)
        //TODO 连接websocket
        object : Thread() {
            override fun run() {
                try {
                    //connectBlocking多出一个等待操作，会先连接再发送，否则未连接发送会报错
                    client?.connectBlocking()
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                }
            }
        }.start()
    }

    /**
     * 发送消息
     *
     * @param msg
     */
    fun sendMsg(msg: String?) {
        if (null != client) {
            LogUtils.e("123", String.format("Websocket发送的消息:%s", msg))
            if (client!!.isOpen) {
                client!!.send(msg)
            }
        }
    }

    /**
     * 开启重连
     */
    private fun reconnectWs() {
        mHandler?.removeCallbacks(heartBeatRunnable)
        object : Thread() {
            override fun run() {
                try {
                    LogUtils.w("123", "开启重连")
                    client!!.reconnectBlocking()
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                }
            }
        }.start()
    }

    /**
     * 断开连接
     */
    private fun closeConnect() {
        try {
            //关闭websocket
            if (null != client) {
                client!!.close()
            }
            //停止心跳
            if (mHandler != null) {
                mHandler.removeCallbacksAndMessages(null)
            }
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            client = null
        }
    }

    private val mHandler: Handler? = Handler()
    private val heartBeatRunnable: Runnable = object : Runnable {
        override fun run() {
            if (client != null) {
                if (client!!.isClosed) {
                    LogUtils.w("123", "心跳包检测websocket连接状态1" + client!!.isOpen + "/" + websocket_url)
                    reconnectWs() //心跳机制发现断开开启重连
                } else {
                    LogUtils.w("123", "心跳包检测websocket连接状态2" + client!!.isOpen + "/" + websocket_url)
                    sendMsg("Heartbeat")
                }
            } else {
                LogUtils.w("123", "心跳包检测websocket连接状态重新连接")
                //如果client已为空，重新初始化连接
                client = null
                initWebSocket()
            }
            //每隔一定的时间，对长连接进行一次心跳检测
            mHandler?.postDelayed(this, HEART_BEAT_RATE)
        }
    }

    init {
//        if(TextUtils.isEmpty(_websocket_url)) {
//            throw new IllegalArgumentException("Invalid websocket URL: " + _websocket_url);
//        }
        if (!TextUtils.isEmpty(_websocket_url)) {
            websocket_url = _websocket_url!!.trim { it <= ' ' }
        }
        listener = _listener
        initWS()
    }

    /**
     * 建造者
     */
    class Builder {
        private var websocket_url: String? = null
        private var listener: ReceiveMsgListener? = null
        fun setWebsocket_url(websocket_url: String?): Builder {
            this.websocket_url = websocket_url
            return this
        }

        fun setListener(listener: ReceiveMsgListener?): Builder {
            this.listener = listener
            return this
        }

        fun build(): WebSocketUtils {
            return WebSocketUtils(websocket_url, listener)
        }
    }

    /**
     * 接收到消息监听
     */
    interface ReceiveMsgListener {
        fun onReceive(message: String?)
        fun onOpen(handshakedata: ServerHandshake?)
        fun onError(ex: Exception?)
        fun onClose(code: Int, reason: String?, remote: Boolean)
    }

    companion object {
        /**
         * WebSocket 心跳逻辑
         * 每隔10秒进行一次对长连接的心跳检测
         */
        private const val HEART_BEAT_RATE = (10 * 1000).toLong()
    }
}